/*******************************************************************************
 * * Copyright 2012 Impetus Infotech.
 *  *
 *  * Licensed under the Apache License, Version 2.0 (the "License");
 *  * you may not use this file except in compliance with the License.
 *  * You may obtain a copy of the License at
 *  *
 *  *      http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  * Unless required by applicable law or agreed to in writing, software
 *  * distributed under the License is distributed on an "AS IS" BASIS,
 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  * See the License for the specific language governing permissions and
 *  * limitations under the License.
 ******************************************************************************/
package cn.ilikes.tools.nosql.jpa.metadatas.processor.processores;

import java.lang.reflect.Field;
import java.util.Arrays;

import javax.persistence.ManyToMany;

import org.slf4j.Logger;

import cn.ilikes.tools.logs.Loggerfactory;
import cn.ilikes.tools.nosql.jpa.metadatas.EntityMetaData;
import cn.ilikes.tools.nosql.jpa.metadatas.elements.Relation;
import cn.ilikes.tools.nosql.jpa.metadatas.processor.validators.EntityValidatorException;
import cn.ilikes.tools.nosql.jpa.unitls.PropertyAccessorHelper;

/**
 * The Class ManyToManyRelationMetadataProcessor.
 * 
 * @author Amresh Singh
 */
public class ManyToManyRelationProcessor implements Processors {
	private static Logger logger = Loggerfactory.instance(ManyToManyRelationProcessor.class);

	public ManyToManyRelationProcessor() {

	}

	@Override
	public void processors(Class<?> clazz, EntityMetaData metadata) throws ElementProcessorException {
		validators(clazz, metadata);
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			ManyToMany ann = field.getAnnotation(ManyToMany.class);
			if (ann == null)
				continue;
			Loggerfactory.info(logger, "add  ManyToMany Relation to   Metadata   " + field.getName() + "  EntityMetadata " + metadata);
			Class<?> targetEntity = PropertyAccessorHelper.getGenericClass(field);
			// now, check annotations
			if (null != ann.targetEntity() && !ann.targetEntity().getSimpleName().equals("void")) {
				targetEntity = ann.targetEntity();
			}

			Relation relation = new Relation(field, targetEntity, field.getType(), ann.fetch(), Arrays.asList(ann.cascade()), Boolean.TRUE, ann.mappedBy(),
					Relation.ForeignKey.MANY_TO_MANY);

			//		boolean isJoinedByFK = field.isAnnotationPresent(JoinColumn.class);
			//		boolean isJoinedByTable = field.isAnnotationPresent(JoinTable.class);
			//
			//		if (isJoinedByFK) {
			//			throw new ElementProcessorException("@JoinColumn not allowed for ManyToMany relationship. Use @JoinTable instead");
			//
			//		} else if (isJoinedByTable) {
			//			JoinTableMetadata jtMetadata = new JoinTableMetadata(field);
			//
			//			relation.setRelatedViaJoinTable(true);
			//			relation.setJoinTableMetadata(jtMetadata);
			//		} else if (relation.getMappedBy() == null || relation.getMappedBy().isEmpty()) {
			//			throw new ElementProcessorException("It's manadatory to use @JoinTable with parent side of ManyToMany relationship.");
			//		}
			//		Loggerfactory.info(logger, "EntityMetadata  " + metadata.getEntityClazz().getSimpleName() + "add Relation  : " + relation);
			//		metadata.addRelation(relationField.getName(), relation);
			//
			//		// Set whether this entity has at least one Join table relation, if not
			//		// already set
			//		if (!metadata.isRelationViaJoinTable()) {
			//			metadata.setRelationViaJoinTable(relation.isRelatedViaJoinTable());
			//		}

			//		Loggerfactory.info(logger, " EntityMetadata  " + metadata.getEntityClazz().getSimpleName() + "   add Relation  : "+ relation);
			//		EntityFieldsImpl entityFields = (EntityFieldsImpl) ((EntityMetaDataImpl) metadata).getEntityField(field.getName());
			//		if (entityFields.getjPAField() == null) {
			//			JPAFieldImpl jpaFieldImpl = new JPAFieldImpl();
			//			jpaFieldImpl.setRelation(relation);
			//			entityFields.setjPAField(jpaFieldImpl);
			//		} else {
			//			if (entityFields.getjPAField().getRelation() != null)
			//				throw new ElementProcessorException("this entity : "+clazz.getSimpleName()+"  field : [ "+field.getName()+" ]   have  relation : " 
			//				                            + entityFields.getjPAField().getRelation().getType()+" ;  but this  set  "+relation.getType());
			//		}
		}
	}

	@Override
	public void validators(Class<?> clazz, EntityMetaData entityMetaData) throws EntityValidatorException {

	}

}
